import cv2
import matplotlib.pyplot as plt
import numpy as np

img = cv2.imread("../images/lena.png")
h, w, _ = img.shape

# 灰度化（变成二维数组）
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 将二维数组展平成一维数组
# 1. 使用matplotlib的方法来绘制直方图
plt.hist(img_gray.flatten(),  # img_gray.flatten()：将二维灰度图像数组展平为一维数组
         bins=256,    # 分箱数，x轴的数值个数
         range=(0, 256),   # x轴的取值范围（左闭右开）
         density=True    # 是否将频率归一化到0-1之间
         )
plt.show()

# 2. 使用OpenCV绘制直方图
# 2.1 先计算直方图--统计灰度图的像素值出现的次数
hist = cv2.calcHist([img_gray],  # 注意图像要放在一个列表中
                    [0],   # 灰度图只有一个通道，所以为0,如果是三通道图，则[0,1,2]
                    None,    # 掩码
                    [256],   # 分箱数
                    [0, 256]   # x轴的取值范围（左闭右开）
                    )   # 返回一个Numpy数组
# 2.2 根据统计到的直方图数据绘制直方图
hist_img = np.zeros([256, 256, 3], np.uint8)
# 可以确定的是宽度（像素值的取值范围） 256， 但是高度（像素值出现的次数）可不是256
# 所以我们需要手动归一化  归一化 = 每个值/最大值   [0,1]
# 但是1px肉眼识别不到，所以这里将归一化后的值乘以256  [0,1]*256 = [0,256] 要留点旁白，所以这里将[0,256]*0.9
min_val, max_val, min__loc, max_loc = cv2.minMaxLoc(hist)
for i in range(256):
    ret = int(hist[i][0] / max_val * 256 * 0.9)
    cv2.line(
        hist_img,
        # 注意区分 图像的y轴与数学的y轴是相反的
        (i, 256),
        (i, 256 - ret),
        [0, 0, 255]
    )
cv2.imshow("hist", hist_img)
plt.show()
cv2.waitKey(0)
